﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

////////////////////////////////////////////////////////////////////////////////
// Обслуживание таблиц ВидыДоступа и ЗначенияДоступа в формах редактирования.

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий таблицы формы ЗначенияДоступа.

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ТаблицаФормы
//
Процедура ЗначенияДоступаПриИзменении(Форма, Элемент) Экспорт
	
	Элементы = Форма.Элементы;
	Параметры = ПараметрыФормыРедактированияРазрешенныхЗначений(Форма);
	
	Если Элемент.ТекущиеДанные <> Неопределено
	   И Элемент.ТекущиеДанные.ВидДоступа = Неопределено Тогда
		
		Отбор = УправлениеДоступомСлужебныйКлиентСервер.ОтборВТаблицахФормыРедактированияРазрешенныхЗначений(
			Форма, Форма.ТекущийВидДоступа);
		
		ЗаполнитьЗначенияСвойств(Элемент.ТекущиеДанные, Отбор);
		
		Элемент.ТекущиеДанные.НомерСтрокиПоВиду = Параметры.ЗначенияДоступа.НайтиСтроки(Отбор).Количество();
	КонецЕсли;
	
	УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьНомераСтрокЗначенийДоступаПоВиду(
		Форма, Элементы.ВидыДоступа.ТекущиеДанные);
	
	УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьВсеРазрешеныПредставление(
		Форма, Элементы.ВидыДоступа.ТекущиеДанные);
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ТаблицаФормы
//  НоваяСтрока - Булево
//  Копирование - Булево
//
Процедура ЗначенияДоступаПриНачалеРедактирования(Форма, Элемент, НоваяСтрока, Копирование) Экспорт
	
	Элементы = Форма.Элементы;
	
	Если Элемент.ТекущиеДанные.ЗначениеДоступа = Неопределено Тогда
		Если Форма.ТекущиеТипыВыбираемыхЗначений.Количество() > 1
		   И Форма.ТекущийВидДоступа <> Форма.ВидДоступаВнешниеПользователи
		   И Форма.ТекущийВидДоступа <> Форма.ВидДоступаПользователи Тогда
			
			Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаВыбора = Истина;
		Иначе
			Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаВыбора = Неопределено;
			Элементы.ЗначенияДоступа.ТекущиеДанные.ЗначениеДоступа = Форма.ТекущиеТипыВыбираемыхЗначений[0].Значение;
			Форма.ТекущийТипВыбираемыхЗначений = Форма.ТекущиеТипыВыбираемыхЗначений[0].Значение
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаОчистки
		= Форма.ТекущийТипВыбираемыхЗначений <> Неопределено
		И Форма.ТекущиеТипыВыбираемыхЗначений.Количество() > 1;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ЗначениеДоступаНачалоВыбора(Форма, Элемент, ДанныеВыбора, СтандартнаяОбработка) Экспорт
	
	СтандартнаяОбработка = Ложь;
	
	Если Форма.ТекущиеТипыВыбираемыхЗначений.Количество() = 1 Тогда
		
		Форма.ТекущийТипВыбираемыхЗначений = Форма.ТекущиеТипыВыбираемыхЗначений[0].Значение;
		
		ЗначениеДоступаНачалоВыбораЗавершение(Форма);
		Возврат;
		
	ИначеЕсли Форма.ТекущиеТипыВыбираемыхЗначений.Количество() > 0 Тогда
		
		Если Форма.ТекущиеТипыВыбираемыхЗначений.Количество() = 2 Тогда
		
			Если Форма.ТекущийВидДоступа = Форма.ВидДоступаПользователи Тогда
				Форма.ТекущийТипВыбираемыхЗначений = ПредопределенноеЗначение(
					"Справочник.Пользователи.ПустаяСсылка");
				
				ЗначениеДоступаНачалоВыбораЗавершение(Форма);
				Возврат;
			КонецЕсли;
			
			Если Форма.ТекущийВидДоступа = Форма.ВидДоступаВнешниеПользователи Тогда
				Форма.ТекущийТипВыбираемыхЗначений = ПредопределенноеЗначение(
					"Справочник.ВнешниеПользователи.ПустаяСсылка");
				
				ЗначениеДоступаНачалоВыбораЗавершение(Форма);
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
		Форма.ТекущиеТипыВыбираемыхЗначений.ПоказатьВыборЭлемента(
			Новый ОписаниеОповещения("ЗначениеДоступаНачалоВыбораПродолжение", ЭтотОбъект, Форма),
			НСтр("ru = 'Выбор типа данных'"),
			Форма.ТекущиеТипыВыбираемыхЗначений[0]);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ТаблицаФормы
//  ВыбранноеЗначение - Произвольный
//  СтандартнаяОбработка - Булево
//
Процедура ЗначениеДоступаОбработкаВыбора(Форма, Элемент, ВыбранноеЗначение, СтандартнаяОбработка) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ЗначенияДоступа.ТекущиеДанные;
	
	Если ВыбранноеЗначение = Тип("СправочникСсылка.Пользователи")
	 Или ВыбранноеЗначение = Тип("СправочникСсылка.ГруппыПользователей") Тогда
	
		СтандартнаяОбработка = Ложь;
		
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("РежимВыбора", Истина);
		ПараметрыФормы.Вставить("ТекущаяСтрока", ТекущиеДанные.ЗначениеДоступа);
		ПараметрыФормы.Вставить("ВыборГруппПользователей", Истина);
		
		ОткрытьФорму("Справочник.Пользователи.ФормаВыбора", ПараметрыФормы, Элемент);
		
	ИначеЕсли ВыбранноеЗначение = Тип("СправочникСсылка.ВнешниеПользователи")
	      Или ВыбранноеЗначение = Тип("СправочникСсылка.ГруппыВнешнихПользователей") Тогда
	
		СтандартнаяОбработка = Ложь;
		
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("РежимВыбора", Истина);
		ПараметрыФормы.Вставить("ТекущаяСтрока", ТекущиеДанные.ЗначениеДоступа);
		ПараметрыФормы.Вставить("ВыборГруппВнешнихПользователей", Истина);
		
		ОткрытьФорму("Справочник.ВнешниеПользователи.ФормаВыбора", ПараметрыФормы, Элемент);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ЗначенияДоступаПриОкончанииРедактирования(Форма, Элемент, НоваяСтрока, ОтменаРедактирования) Экспорт
	
	Если Форма.ТекущийВидДоступа = Неопределено Тогда
		Параметры = ПараметрыФормыРедактированияРазрешенныхЗначений(Форма);
		
		Отбор = Новый Структура("ВидДоступа", Неопределено);
		
		НайденныеСтроки = Параметры.ЗначенияДоступа.НайтиСтроки(Отбор);
		
		Для каждого Строка Из НайденныеСтроки Цикл
			Параметры.ЗначенияДоступа.Удалить(Строка);
		КонецЦикла;
		
		ОтменаРедактирования = Истина;
	КонецЕсли;
	
	Если ОтменаРедактирования Тогда
		УправлениеДоступомСлужебныйКлиентСервер.ПриИзмененииТекущегоВидаДоступа(Форма);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ПолеФормы
//  СтандартнаяОбработка - Булево
//
Процедура ЗначениеДоступаОчистка(Форма, Элемент, СтандартнаяОбработка) Экспорт
	
	Элементы = Форма.Элементы;
	
	СтандартнаяОбработка = Ложь;
	Форма.ТекущийТипВыбираемыхЗначений = Неопределено;
	Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаОчистки = Ложь;
	
	Если Форма.ТекущиеТипыВыбираемыхЗначений.Количество() > 1
	   И Форма.ТекущийВидДоступа <> Форма.ВидДоступаВнешниеПользователи
	   И Форма.ТекущийВидДоступа <> Форма.ВидДоступаПользователи Тогда
		
		Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаВыбора = Истина;
		Элементы.ЗначенияДоступа.ТекущиеДанные.ЗначениеДоступа = Неопределено;
	Иначе
		Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаВыбора = Неопределено;
		Элементы.ЗначенияДоступа.ТекущиеДанные.ЗначениеДоступа = Форма.ТекущиеТипыВыбираемыхЗначений[0].Значение;
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ЗначениеДоступаАвтоПодбор(Форма, Элемент, Текст, ДанныеВыбора, Ожидание, СтандартнаяОбработка) Экспорт
	
	СформироватьДанныеВыбораЗначенияДоступа(Форма, Текст, ДанныеВыбора, СтандартнаяОбработка);
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ЗначениеДоступаОкончаниеВводаТекста(Форма, Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка) Экспорт
	
	СформироватьДанныеВыбораЗначенияДоступа(Форма, Текст, ДанныеВыбора, СтандартнаяОбработка);
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий таблицы формы ВидыДоступа.

// Только для внутреннего использования.
Процедура ВидыДоступаПриАктивизацииСтроки(Форма, Элемент) Экспорт
	
	УправлениеДоступомСлужебныйКлиентСервер.ПриИзмененииТекущегоВидаДоступа(Форма);
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ТаблицаФормы
//
Процедура ВидыДоступаПриАктивизацииЯчейки(Форма, Элемент) Экспорт
	
	Если Форма.ЭтоПрофильГруппДоступа Тогда
		Возврат;
	КонецЕсли;
	
	Элементы = Форма.Элементы;
	
	Если Элементы.ВидыДоступа.ТекущийЭлемент <> Элементы.ВидыДоступаВсеРазрешеныПредставление Тогда
		Элементы.ВидыДоступа.ТекущийЭлемент = Элементы.ВидыДоступаВсеРазрешеныПредставление;
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ВидыДоступаПередНачаломДобавления(Форма, Элемент, Отказ, Копирование, Родитель, Группа) Экспорт
	
	Если Копирование Тогда
		Отказ = Истина;
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ВидыДоступаПередУдалением(Форма, Элемент, Отказ) Экспорт
	
	Форма.ТекущийВидДоступа = Неопределено;
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ТаблицаФормы
//  НоваяСтрока - Булево
//  Копирование - Булево
//
Процедура ВидыДоступаПриНачалеРедактирования(Форма, Элемент, НоваяСтрока, Копирование) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ВидыДоступа.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если НоваяСтрока Тогда
		ТекущиеДанные.Используется = Истина;
	КонецЕсли;
	
	УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьВсеРазрешеныПредставление(Форма, ТекущиеДанные, Ложь);
	
КонецПроцедуры

// Только для внутреннего использования.
Процедура ВидыДоступаПриОкончанииРедактирования(Форма, Элемент, НоваяСтрока, ОтменаРедактирования) Экспорт
	
	УправлениеДоступомСлужебныйКлиентСервер.ПриИзмененииТекущегоВидаДоступа(Форма);
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ПолеФормы
//
Процедура ВидыДоступаВидДоступаПредставлениеПриИзменении(Форма, Элемент) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ВидыДоступа.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ВидДоступаПредставление = "" Тогда
		ТекущиеДанные.ВидДоступа   = Неопределено;
		ТекущиеДанные.Используется = Истина;
	КонецЕсли;
	
	УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьСвойстваВидовДоступаВФорме(Форма);
	УправлениеДоступомСлужебныйКлиентСервер.ПриИзмененииТекущегоВидаДоступа(Форма);
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ПолеФормы
//  ВыбранноеЗначение - Произвольный
//  СтандартнаяОбработка - Булево
// 
Процедура ВидыДоступаВидДоступаПредставлениеОбработкаВыбора(Форма, Элемент, ВыбранноеЗначение, СтандартнаяОбработка) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ВидыДоступа.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		СтандартнаяОбработка = Ложь;
		Возврат;
	КонецЕсли;
	
	Параметры = ПараметрыФормыРедактированияРазрешенныхЗначений(Форма);
	
	Отбор = Новый Структура("ВидДоступаПредставление", ВыбранноеЗначение);
	Строки = Параметры.ВидыДоступа.НайтиСтроки(Отбор);
	
	Если Строки.Количество() > 0
	   И Строки[0].ПолучитьИдентификатор() <> Форма.Элементы.ВидыДоступа.ТекущаяСтрока Тогда
		
		ПоказатьПредупреждение(, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Вид доступа ""%1"" уже выбран.
			           |Выберите другой.'"),
			ВыбранноеЗначение));
		
		СтандартнаяОбработка = Ложь;
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("Представление", ВыбранноеЗначение);
	ТекущиеДанные.ВидДоступа = Форма.ВсеВидыДоступа.НайтиСтроки(Отбор)[0].Ссылка;
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ПолеФормы
//
Процедура ВидыДоступаВсеРазрешеныПредставлениеПриИзменении(Форма, Элемент) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ВидыДоступа.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТекущиеДанные.ВсеРазрешеныПредставление = "" Тогда
		ТекущиеДанные.ВсеРазрешены = Ложь;
		Если Форма.ЭтоПрофильГруппДоступа Тогда
			ТекущиеДанные.Предустановленный = Ложь;
		КонецЕсли;
	КонецЕсли;
	
	Если Форма.ЭтоПрофильГруппДоступа Тогда
		УправлениеДоступомСлужебныйКлиентСервер.ПриИзмененииТекущегоВидаДоступа(Форма);
		УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьВсеРазрешеныПредставление(Форма, ТекущиеДанные, Ложь);
	Иначе
		Форма.Элементы.ВидыДоступа.ЗакончитьРедактированиеСтроки(Ложь);
		УправлениеДоступомСлужебныйКлиентСервер.ЗаполнитьВсеРазрешеныПредставление(Форма, ТекущиеДанные);
	КонецЕсли;
	
КонецПроцедуры

// Только для внутреннего использования.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//  Элемент - ПолеФормы
//  ВыбранноеЗначение - Произвольный
//  СтандартнаяОбработка - Булево
//
Процедура ВидыДоступаВсеРазрешеныПредставлениеОбработкаВыбора(Форма, Элемент, ВыбранноеЗначение, СтандартнаяОбработка) Экспорт
	
	ТекущиеДанные = Форма.Элементы.ВидыДоступа.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		СтандартнаяОбработка = Ложь;
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("Представление", ВыбранноеЗначение);
	Имя = Форма.ПредставленияВсеРазрешены.НайтиСтроки(Отбор)[0].Имя;
	
	Если Форма.ЭтоПрофильГруппДоступа Тогда
		ТекущиеДанные.Предустановленный = (Имя = "ВсеРазрешены" ИЛИ Имя = "ВсеЗапрещены");
	КонецЕсли;
	
	ТекущиеДанные.ВсеРазрешены = (Имя = "ВначалеВсеРазрешены" ИЛИ Имя = "ВсеРазрешены");
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий общей формы ФормаОтчета.

// Обработчик двойного щелчка мыши, нажатия клавиши Enter или гиперссылки в табличном документе формы отчета.
// См. "Расширение поля формы для поля табличного документа.Выбор" в синтакс-помощнике.
//
// Параметры:
//   ФормаОтчета          - ФормаКлиентскогоПриложения - форма отчета.
//   Элемент              - ПолеФормы        - табличный документ.
//   Область              - ОбластьЯчеекТабличногоДокумента - выбранное значение.
//   СтандартнаяОбработка - Булево - признак выполнения стандартной обработки события.
//
Процедура ОбработкаВыбораТабличногоДокумента(ФормаОтчета, Элемент, Область, СтандартнаяОбработка) Экспорт
	
	Если ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.ПраваДоступа"
	   И ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента")
	   И Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник
	   И ТипЗнч(Область.Расшифровка) = Тип("Строка")
	   И СтрНачинаетсяС(Область.Расшифровка, "ОткрытьФормуСписка: ") Тогда
			
		СтандартнаяОбработка = Ложь;
		ОткрытьФорму(Сред(Область.Расшифровка, СтрДлина("ОткрытьФормуСписка: ") + 1) + ".ФормаСписка");
		Возврат;
	КонецЕсли;
	
	Если ФормаОтчета.НастройкиОтчета.ПолноеИмя <> "Отчет.АнализПравДоступа" Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(Область) = Тип("ОбластьЯчеекТабличногоДокумента")
		И Область.ТипОбласти = ТипОбластиЯчеекТабличногоДокумента.Прямоугольник
		И Область.Расшифровка <> Неопределено Тогда
		
		ФормаОтчета.ОбработкаРасшифровки = Истина;
	КонецЕсли;
	
КонецПроцедуры

// См. ОтчетыКлиентПереопределяемый.ОбработкаРасшифровки
Процедура ПриОбработкеРасшифровки(ФормаОтчета, Элемент, Расшифровка, СтандартнаяОбработка) Экспорт
	
	Если ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.АнализПравДоступа" Тогда
		ПриОбработкеРасшифровкиОтчетаАнализПравДоступа(ФормаОтчета,
			Элемент, Расшифровка, СтандартнаяОбработка);
	
	ИначеЕсли ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.ПраваРолей" Тогда
		ПриОбработкеРасшифровкиОтчетаПраваРолей(ФормаОтчета,
			Элемент, Расшифровка, СтандартнаяОбработка);
	КонецЕсли;
	
КонецПроцедуры

// См. ОтчетыКлиентПереопределяемый.ПриНачалеВыбораЗначений
Процедура ПриНачалеВыбораЗначений(ФормаОтчета, УсловияВыбора, ОповещениеОЗакрытии, СтандартнаяОбработка) Экспорт
	
	Если ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.АнализПравДоступа" Тогда
		ПриНачалеВыбораЗначенийОтчетаАнализПравДоступа(ФормаОтчета,
			УсловияВыбора, ОповещениеОЗакрытии, СтандартнаяОбработка);
	
	ИначеЕсли ФормаОтчета.НастройкиОтчета.ПолноеИмя = "Отчет.ПраваРолей" Тогда
		ПриНачалеВыбораЗначенийОтчетаПраваРолей(ФормаОтчета,
			УсловияВыбора, ОповещениеОЗакрытии, СтандартнаяОбработка);
	КонецЕсли;
	
КонецПроцедуры

Процедура ПоказатьПраваПользователяНаТаблицы(Пользователь) Экспорт
	
	Отбор = Новый Структура("Пользователь", Пользователь);
	КлючВарианта = "ПраваПользователяНаТаблицы";
	КлючНазначенияИспользования = КлючВарианта;
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "Пользователь");
	СократитьКлючНазначенияИспользования(КлючНазначенияИспользования);
	
	ПараметрыОтчета = Новый Структура;
	ПараметрыОтчета.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыОтчета.Вставить("Отбор", Отбор);
	ПараметрыОтчета.Вставить("КлючВарианта", КлючВарианта);
	ПараметрыОтчета.Вставить("КлючНазначенияИспользования", КлючНазначенияИспользования);
	
	ОткрытьФорму("Отчет.АнализПравДоступа.Форма", ПараметрыОтчета, ЭтотОбъект);
	
КонецПроцедуры

Процедура ПоказатьПраваПользователейОтчета(Отчет, ИспользуемыеТаблицы) Экспорт
	
	КлючВарианта = "ПраваПользователейНаТаблицыОтчета";
	
	Отбор = Новый Структура;
	Отбор.Вставить("Отчет", Отчет);
	Отбор.Вставить("ВходВПрограммуРазрешен", Истина);
	
	ПараметрыОтчета = Новый Структура;
	ПараметрыОтчета.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыОтчета.Вставить("Отбор", Отбор);
	ПараметрыОтчета.Вставить("КлючВарианта", КлючВарианта);
	ПараметрыОтчета.Вставить("КлючНазначенияИспользования", КлючВарианта);
	ПараметрыОтчета.Вставить("ИспользуемыеТаблицы", ИспользуемыеТаблицы);
	
	ОткрытьФорму("Отчет.АнализПравДоступа.Форма", ПараметрыОтчета, ЭтотОбъект);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Продолжение обработчика события ЗначениеДоступаНачалоВыбора.
Процедура ЗначениеДоступаНачалоВыбораПродолжение(ВыбранныйЭлемент, Форма) Экспорт
	
	Если ВыбранныйЭлемент <> Неопределено Тогда
		Форма.ТекущийТипВыбираемыхЗначений = ВыбранныйЭлемент.Значение;
		ЗначениеДоступаНачалоВыбораЗавершение(Форма);
	КонецЕсли;
	
КонецПроцедуры

// Завершение обработчика события ЗначениеДоступаНачалоВыбора.
// 
// Параметры:
//  Форма - см. УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений
//
Процедура ЗначениеДоступаНачалоВыбораЗавершение(Форма)
	
	Элементы = Форма.Элементы;
	Элемент  = Элементы.ЗначенияДоступаЗначениеДоступа;
	ТекущиеДанные = Элементы.ЗначенияДоступа.ТекущиеДанные;
	
	Если НЕ ЗначениеЗаполнено(ТекущиеДанные.ЗначениеДоступа)
	   И ТекущиеДанные.ЗначениеДоступа <> Форма.ТекущийТипВыбираемыхЗначений Тогда
		
		ТекущиеДанные.ЗначениеДоступа = Форма.ТекущийТипВыбираемыхЗначений;
	КонецЕсли;
	
	Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаВыбора = Неопределено;
	Элементы.ЗначенияДоступаЗначениеДоступа.КнопкаОчистки
		= Форма.ТекущийТипВыбираемыхЗначений <> Неопределено
		И Форма.ТекущиеТипыВыбираемыхЗначений.Количество() > 1;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("РежимВыбора", Истина);
	ПараметрыФормы.Вставить("ТекущаяСтрока", ТекущиеДанные.ЗначениеДоступа);
	ПараметрыФормы.Вставить("ЭтоВыборЗначенияДоступа");
	
	Если Форма.ТекущийВидДоступа = Форма.ВидДоступаПользователи Тогда
		ПараметрыФормы.Вставить("ВыборГруппПользователей", Истина);
		ОткрытьФорму("Справочник.Пользователи.ФормаВыбора", ПараметрыФормы, Элемент);
		Возврат;
		
	ИначеЕсли Форма.ТекущийВидДоступа = Форма.ВидДоступаВнешниеПользователи Тогда
		ПараметрыФормы.Вставить("ВыборГруппВнешнихПользователей", Истина);
		ОткрытьФорму("Справочник.ВнешниеПользователи.ФормаВыбора", ПараметрыФормы, Элемент);
		Возврат;
	КонецЕсли;
	
	Отбор = Новый Структура("ТипЗначений", Форма.ТекущийТипВыбираемыхЗначений);
	НайденныеСтроки = Форма.ВсеТипыВыбираемыхЗначений.НайтиСтроки(Отбор);
	
	Если НайденныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Если НайденныеСтроки[0].ИерархияЭлементов Тогда
		ПараметрыФормы.Вставить("ВыборГруппИЭлементов", ИспользованиеГруппИЭлементов.ГруппыИЭлементы);
	КонецЕсли;
	
	ОткрытьФорму(НайденныеСтроки[0].ИмяТаблицы + ".ФормаВыбора", ПараметрыФормы, Элемент);
	
КонецПроцедуры

// Обслуживание таблиц ВидыДоступа и ЗначенияДоступа в формах редактирования.

Функция ПараметрыФормыРедактированияРазрешенныхЗначений(Форма, ТекущийОбъект = Неопределено)
	
	Возврат УправлениеДоступомСлужебныйКлиентСервер.ПараметрыФормыРедактированияРазрешенныхЗначений(
		Форма, ТекущийОбъект);
	
КонецФункции

Процедура СформироватьДанныеВыбораЗначенияДоступа(Форма, Текст, ДанныеВыбора, СтандартнаяОбработка)
	
	Если Не ЗначениеЗаполнено(Текст) Тогда
		Возврат;
	КонецЕсли;
		
	Если Форма.ТекущийВидДоступа <> Форма.ВидДоступаВнешниеПользователи
	   И Форма.ТекущийВидДоступа <> Форма.ВидДоступаПользователи Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	ДанныеВыбора = УправлениеДоступомСлужебныйВызовСервера.СформироватьДанныеВыбораПользователя(Текст,
		Ложь,
		Форма.ТекущийВидДоступа = Форма.ВидДоступаВнешниеПользователи,
		Форма.ТекущийВидДоступа <> Форма.ВидДоступаПользователи);
	
КонецПроцедуры

// Обработка расшифровки отчета.

// Для процедуры ПриОбработкеРасшифровки.
Процедура ПриОбработкеРасшифровкиОтчетаАнализПравДоступа(ФормаОтчета, Элемент, Расшифровка, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ПараметрыРасшифровки = УправлениеДоступомСлужебныйВызовСервера.ПараметрыРасшифровкиОтчетаАнализПравДоступа(
		ФормаОтчета.ОтчетДанныеРасшифровки, Расшифровка);
	
	Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "ЗначениеПрава" Тогда
		Возврат;
	ИначеЕсли ПараметрыРасшифровки.ИмяПоляРасшифровки = "ВладелецИлиПользовательНастроек" Тогда
		Если ПараметрыРасшифровки.СписокПолей.Получить("ЭтоВладелецНастроек") <> Истина Тогда
			СтандартнаяОбработка = Истина;
			Возврат;
		КонецЕсли;
		ВладелецНастроек = ПараметрыРасшифровки.СписокПолей.Получить("ВладелецИлиПользовательНастроек");
		Если Не ЗначениеЗаполнено(ВладелецНастроек) Тогда
			Возврат;
		КонецЕсли;
		ПараметрыФормы = Новый Структура("СсылкаНаОбъект", ВладелецНастроек);
		ОткрытьФорму("ОбщаяФорма.НастройкиПравОбъектов", ПараметрыФормы);
		Возврат;
	ИначеЕсли ПараметрыРасшифровки.ИмяПоляРасшифровки = "ЗначениеДоступа" Тогда
		ГруппаДоступа = ПараметрыРасшифровки.СписокПолей.Получить("ГруппаДоступа");
		Если Не ЗначениеЗаполнено(ГруппаДоступа)
		 Или ТипЗнч(ГруппаДоступа) <> Тип("СправочникСсылка.ГруппыДоступа") Тогда
			Возврат;
		КонецЕсли;
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("Ключ", ГруппаДоступа);
		ПараметрыФормы.Вставить("ПерейтиКВидуДоступа",
			ПараметрыРасшифровки.СписокПолей.Получить("ВидДоступа"));
		ПараметрыФормы.Вставить("ПерейтиКЗначениюДоступа",
			ПараметрыРасшифровки.СписокПолей.Получить("ЗначениеДоступа"));
		Форма = ОткрытьФорму("Справочник.ГруппыДоступа.ФормаОбъекта", ПараметрыФормы);
		ПараметрыФормы.Удалить("Ключ");
		ЗаполнитьЗначенияСвойств(Форма, ПараметрыФормы);
		Возврат;
	КонецЕсли;
	
	ТекущийВариант = ФормаОтчета.Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.КлючПредопределенногоВарианта;
	
	ПараметрыОтчета = Новый Структура;
	ПараметрыОтчета.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыОтчета.Вставить("Расшифровка", Расшифровка);
	
	Отбор = Новый Структура;
	Для Каждого ЭлементОтбора Из ФормаОтчета.Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
		Настройка = ФормаОтчета.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(
			ЭлементОтбора.ИдентификаторПользовательскойНастройки);
		Если Настройка = Неопределено Тогда
			Настройка = ЭлементОтбора;
		КонецЕсли;
		Если Настройка.Использование Тогда
			Если ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно
			 Или ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке Тогда
				
				Отбор.Вставить(ЭлементОтбора.ЛевоеЗначение, Настройка.ПравоеЗначение);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	ИмяПараметра = "Пользователь";
	ЗначениеПараметра = ЗначениеПараметра(ФормаОтчета.Отчет.КомпоновщикНастроек, ИмяПараметра);
	Если ЗначениеПараметра <> Null Тогда
		Отбор.Вставить(ИмяПараметра, ЗначениеПараметра);
	КонецЕсли;
	
	Если ТекущийВариант = "ПраваПользователейНаТаблицыОтчета"
	   И ПараметрыРасшифровки.ИмяПоляРасшифровки <> "Пользователь"
	 Или ТекущийВариант = "ПраваПользователяНаТаблицыОтчета" Тогда
		
		Отбор.Удалить("Отчет");
	КонецЕсли;
	
	Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "Право"
	 Или ПараметрыРасшифровки.ИмяПоляРасшифровки = "ПравоПросмотр"
	 Или ПараметрыРасшифровки.ИмяПоляРасшифровки = "ПравоРедактирование"
	 Или ПараметрыРасшифровки.ИмяПоляРасшифровки = "ПравоИнтерактивноеДобавление" Тогда
		
		КлючВарианта = "ПраваПользователяНаТаблицу";
		
		Если ПараметрыРасшифровки.СписокПолей["Пользователь"] <> Неопределено Тогда
			Отбор.Вставить("Пользователь", ПараметрыРасшифровки.СписокПолей["Пользователь"]);
		КонецЕсли;
		
		Если ПараметрыРасшифровки.СписокПолей["ОбъектМетаданных"] <> Неопределено Тогда
			Отбор.Вставить("ОбъектМетаданных", ПараметрыРасшифровки.СписокПолей["ОбъектМетаданных"]);
		ИначеЕсли ПараметрыРасшифровки.СписокПолей["Отчет"] <> Неопределено Тогда
			Отбор.Вставить("Отчет", ПараметрыРасшифровки.СписокПолей["Отчет"]);
			КлючВарианта = "ПраваПользователяНаТаблицыОтчета";
		КонецЕсли;
		
		Если КлючВарианта = ТекущийВариант Тогда
			Возврат;
		КонецЕсли;
		
		Если КлючВарианта <> "ПраваПользователяНаТаблицыОтчета" Тогда
			ЗначениеПрава = ПараметрыРасшифровки.СписокПолей[ПараметрыРасшифровки.ИмяПоляРасшифровки];
			Если ТипЗнч(ЗначениеПрава) = Тип("Число")  И ЗначениеПрава = 0
			 Или ТипЗнч(ЗначениеПрава) = Тип("Булево") И Не ЗначениеПрава Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
	ИначеЕсли ПараметрыРасшифровки.ИмяПоляРасшифровки = "ОбъектМетаданных" Тогда
		
		КлючВарианта = "ПраваПользователейНаТаблицу";
		Отбор.Вставить("ОбъектМетаданных", ПараметрыРасшифровки.СписокПолей["ОбъектМетаданных"]);

		Если ТекущийВариант = "ПраваПользователяНаТаблицы"
			Или ТекущийВариант = "ПраваПользователяНаТаблицыОтчета" Тогда
			КлючВарианта = "ПраваПользователяНаТаблицу";
		КонецЕсли;
		
	ИначеЕсли ПараметрыРасшифровки.ИмяПоляРасшифровки = "Пользователь" 
		И ТекущийВариант <> "ПраваПользователяНаТаблицы"
		И ТекущийВариант <> "ПраваПользователяНаТаблицу"
		И ТекущийВариант <> "ПраваПользователяНаТаблицыОтчетов" Тогда
		
		КлючВарианта = "ПраваПользователяНаТаблицы";
		Отбор.Вставить("Пользователь", ПараметрыРасшифровки.СписокПолей["Пользователь"]);
		Отбор.Удалить("ВходВПрограммуРазрешен");
		
		Если ТекущийВариант = "ПраваПользователейНаТаблицу" Тогда
			КлючВарианта = "ПраваПользователяНаТаблицу";
		КонецЕсли;
		
		Если ТекущийВариант = "ПраваПользователейНаТаблицыОтчета" Тогда
			КлючВарианта = "ПраваПользователяНаТаблицыОтчета";
		КонецЕсли;
		
		Если ТекущийВариант = "АнализПравДоступа"
		   И ГруппировкаПоОтчетамВключена(ФормаОтчета.Отчет.КомпоновщикНастроек) Тогда
			
			КлючВарианта = "ПраваПользователяНаТаблицыОтчетов";
		КонецЕсли;
		
	ИначеЕсли ПараметрыРасшифровки.ИмяПоляРасшифровки = "Отчет" Тогда
		
		Если ТекущийВариант = "ПраваПользователяНаТаблицыОтчета"
		 Или ТекущийВариант = "ПраваПользователейНаТаблицыОтчета" Тогда
			Возврат;
		КонецЕсли;
		
		КлючВарианта = "ПраваПользователейНаТаблицыОтчета";
		Отбор.Вставить("Отчет", ПараметрыРасшифровки.СписокПолей["Отчет"]);
		
	Иначе
		
		ЗначениеРасшифровки = ПараметрыРасшифровки.СписокПолей[ПараметрыРасшифровки.ИмяПоляРасшифровки];
		Если ЗначениеЗаполнено(ЗначениеРасшифровки) Тогда
			Пользователь = ПараметрыРасшифровки.СписокПолей["Пользователь"];
			
			Если Пользователь = Неопределено
			   И Отбор.Свойство("Пользователь")
			   И ТипЗнч(Отбор.Пользователь) = Тип("СправочникСсылка.Пользователи") Тогда
				
				Пользователь = Отбор.Пользователь;
			КонецЕсли;
				
			Если ЗначениеЗаполнено(Пользователь)
			   И ТипЗнч(ЗначениеРасшифровки) = Тип("СправочникСсылка.ПрофилиГруппДоступа") Тогда
				
				ПараметрыРаботыКлиента = СтандартныеПодсистемыКлиент.ПараметрыРаботыКлиента();
				Если ПараметрыРаботыКлиента.УпрощенныйИнтерфейсНастройкиПравДоступа Тогда
					ИмяФормы = "ОбщаяФорма.ПраваДоступаУпрощенно";
				Иначе
					ИмяФормы = "ОбщаяФорма.ПраваДоступа";
				КонецЕсли;
				
				Форма = ОткрытьФорму("Справочник.Пользователи.ФормаОбъекта", Новый Структура("Ключ", Пользователь));
				ОткрытьФорму(ИмяФормы, Новый Структура("Пользователь", Пользователь), Форма, , Форма.Окно);
			Иначе
				ПоказатьЗначение(Неопределено,
					ПараметрыРасшифровки.СписокПолей[ПараметрыРасшифровки.ИмяПоляРасшифровки]);
			КонецЕсли;
		КонецЕсли;
		
		Возврат;
		
	КонецЕсли;
	
	Если Отбор.Свойство("ОбъектМетаданных")
	   И Не ЗначениеЗаполнено(Отбор.ОбъектМетаданных)
	   И (    КлючВарианта = "ПраваПользователейНаТаблицу"
	      Или КлючВарианта = "ПраваПользователяНаТаблицу" ) Тогда
		
		Возврат;
	КонецЕсли;
	
	КлючНазначенияИспользования = КлючВарианта;
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "Отчет");
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "Пользователь");
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "ОбъектМетаданных");
	СократитьКлючНазначенияИспользования(КлючНазначенияИспользования);
	
	ПараметрыОтчета.Вставить("Отбор", Отбор);
	ПараметрыОтчета.Вставить("КлючВарианта", КлючВарианта);
	ПараметрыОтчета.Вставить("КлючНазначенияИспользования", КлючНазначенияИспользования);
	
	ОткрытьФорму(ФормаОтчета.НастройкиОтчета.ПолноеИмя + ".Форма", ПараметрыОтчета, ФормаОтчета);
	
КонецПроцедуры

// Для процедуры ПриОбработкеРасшифровки.
Процедура ПриОбработкеРасшифровкиОтчетаПраваРолей(ФормаОтчета, Элемент, Расшифровка, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	ПараметрыРасшифровки = УправлениеДоступомСлужебныйВызовСервера.ПараметрыРасшифровкиОтчетаАнализПравДоступа(
		ФормаОтчета.ОтчетДанныеРасшифровки, Расшифровка);
	
	Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "Профиль" Тогда
		Профиль = ПараметрыРасшифровки.СписокПолей["Профиль"];
		Если ТипЗнч(Профиль) = Тип("СправочникСсылка.ПрофилиГруппДоступа")
		   И ЗначениеЗаполнено(Профиль) Тогда
			ПоказатьЗначение(, Профиль);
		КонецЕсли;
		Возврат;
	КонецЕсли;
	
	ТекущийВариант = ФормаОтчета.Отчет.КомпоновщикНастроек.Настройки.ДополнительныеСвойства.КлючПредопределенногоВарианта;
	Если ТекущийВариант = "ПодробныеПраваРолиНаОбъектМетаданных" Тогда
		Возврат;
	КонецЕсли;
	
	ПараметрыОтчета = Новый Структура;
	ПараметрыОтчета.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыОтчета.Вставить("Расшифровка", Расшифровка);
	
	Отбор = Новый Структура;
	УстановитьЗначениеПараметра(Отбор, "ФорматИмени", ФормаОтчета);
	
	Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "УровеньДоступа" Тогда
		Если ЗначениеЗаполнено(ПараметрыРасшифровки.СписокПолей["ПолноеИмяОбъекта"]) Тогда
			Отбор.Вставить("ОбъектМетаданных", ПараметрыРасшифровки.СписокПолей["ПолноеИмяОбъекта"]);
		Иначе
			Свойства = Новый Структура("ОтчетТабличныйДокумент");
			ЗаполнитьЗначенияСвойств(Свойства, ФормаОтчета);
			Если ТипЗнч(Свойства.ОтчетТабличныйДокумент) <> Тип("ТабличныйДокумент") Тогда
				Возврат;
			КонецЕсли;
			ОбластьОбъекта = Свойства.ОтчетТабличныйДокумент.Область(Элемент.ТекущаяОбласть.Верх, 2);
			Если ТипЗнч(ОбластьОбъекта.Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
				Возврат;
			КонецЕсли;
			ПараметрыРасшифровкиОбъекта = УправлениеДоступомСлужебныйВызовСервера.ПараметрыРасшифровкиОтчетаАнализПравДоступа(
				ФормаОтчета.ОтчетДанныеРасшифровки, ОбластьОбъекта.Расшифровка);
			Если ЗначениеЗаполнено(ПараметрыРасшифровкиОбъекта.СписокПолей["ПолноеИмяОбъекта"]) Тогда
				Отбор.Вставить("ОбъектМетаданных", ПараметрыРасшифровкиОбъекта.СписокПолей["ПолноеИмяОбъекта"]);
			Иначе
				Возврат;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Если ТекущийВариант = "ПраваРолей"
	   И ПараметрыРасшифровки.ИмяПоляРасшифровки = "УровеньДоступа" Тогда
		
		КлючВарианта = "ПодробныеПраваРолиНаОбъектМетаданных";
		
		Если ЗначениеЗаполнено(ПараметрыРасшифровки.СписокПолей["ИмяРоли"]) Тогда
			Отбор.Вставить("Роль", ПараметрыРасшифровки.СписокПолей["ИмяРоли"]);
		ИначеЕсли ТипЗнч(ПараметрыРасшифровкиОбъекта) = Тип("Структура") Тогда
			НомерСтрокиЭлемента = ПараметрыРасшифровкиОбъекта.СписокПолей["НомерСтрокиЭлемента"];
			Если Не ЗначениеЗаполнено(НомерСтрокиЭлемента) Тогда
				Возврат;
			КонецЕсли;
			ОбластьРоли = Свойства.ОтчетТабличныйДокумент.Область(Элемент.ТекущаяОбласть.Верх - НомерСтрокиЭлемента,
				Элемент.ТекущаяОбласть.Лево);
			Если ТипЗнч(ОбластьРоли.Расшифровка) <> Тип("ИдентификаторРасшифровкиКомпоновкиДанных") Тогда
				Возврат;
			КонецЕсли;
			ПараметрыРасшифровкиРоли = УправлениеДоступомСлужебныйВызовСервера.ПараметрыРасшифровкиОтчетаАнализПравДоступа(
				ФормаОтчета.ОтчетДанныеРасшифровки, ОбластьРоли.Расшифровка);
			Если ЗначениеЗаполнено(ПараметрыРасшифровкиРоли.СписокПолей["ИмяРоли"]) Тогда
				Отбор.Вставить("Роль", ПараметрыРасшифровкиРоли.СписокПолей["ИмяРоли"]);
			Иначе
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
	ИначеЕсли ТекущийВариант = "ПраваРолей"
	        И ПараметрыРасшифровки.ИмяПоляРасшифровки = "ИмяРоли" Тогда
		
		КлючВарианта = "ПраваРолиНаОбъектыМетаданных";
		
		ИмяРоли = ПараметрыРасшифровки.СписокПолей["ИмяРоли"];
		Если Не ЗначениеЗаполнено(ИмяРоли) Тогда
			Возврат;
		КонецЕсли;
		Отбор.Вставить("Роль", ИмяРоли);
		УстановитьЗначениеПараметра(Отбор, "ОбъектМетаданных", ФормаОтчета);
		УстановитьЗначениеПараметра(Отбор, "ПраваНаРеквизиты", ФормаОтчета, Истина);
		УстановитьЗначениеПараметра(Отбор, "ПоказыватьПраваНеинтерфейсныхПодсистем", ФормаОтчета, Истина);
		УстановитьЗначениеПараметра(Отбор, "НеПредупреждатьОБольшомРазмереОтчета", ФормаОтчета, Истина);
		
	ИначеЕсли ТекущийВариант = "ПраваРолей"
	        И ПараметрыРасшифровки.ИмяПоляРасшифровки = "Уровень" Тогда
		
		КлючВарианта = "ПраваРолейНаОбъектМетаданных";
		
		ПолноеИмяОбъекта = ПараметрыРасшифровки.СписокПолей["ПолноеИмяОбъекта"];
		Если Не ЗначениеЗаполнено(ПолноеИмяОбъекта) Тогда
			Возврат;
		КонецЕсли;
		Отбор.Вставить("ОбъектМетаданных", ПолноеИмяОбъекта);
		УстановитьЗначениеПараметра(Отбор, "Роль", ФормаОтчета);
		
	ИначеЕсли ТекущийВариант = "ПраваРолейНаОбъектМетаданных"
	        И (    ПараметрыРасшифровки.ИмяПоляРасшифровки = "ЕстьОграничение"
	           Или ПараметрыРасшифровки.ИмяПоляРасшифровки = "ИмяРоли3") Тогда
		
		КлючВарианта = "ПодробныеПраваРолиНаОбъектМетаданных";
		
		Отбор.Вставить("ОбъектМетаданных", ЗначениеНачальногоОтбора(ФормаОтчета, "ОбъектМетаданных"));
		Если Не ЗначениеЗаполнено(Отбор.ОбъектМетаданных) Тогда
			Возврат;
		КонецЕсли;
		Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "ИмяРоли3" Тогда
			Отбор.Вставить("Роль", ПараметрыРасшифровки.СписокПолей["ИмяРоли3"]);
		Иначе
			Отбор.Вставить("Профиль", ПараметрыРасшифровки.СписокПолей["Профиль3"]);
			Если Не ЗначениеЗаполнено(Отбор.Профиль) Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
		
	ИначеЕсли ТекущийВариант = "ПраваРолиНаОбъектыМетаданных" Тогда
		
		КлючВарианта = "ПодробныеПраваРолиНаОбъектМетаданных";
		
		Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "Уровень" Тогда
			Отбор.Вставить("ОбъектМетаданных", ПараметрыРасшифровки.СписокПолей["ПолноеИмяОбъекта"]);
		КонецЕсли;
		Если Не Отбор.Свойство("ОбъектМетаданных")
		 Или Не ЗначениеЗаполнено(Отбор.ОбъектМетаданных) Тогда
			Возврат;
		КонецЕсли;
		Если ПараметрыРасшифровки.ИмяПоляРасшифровки = "УровеньДоступа" Тогда
			Отбор.Вставить("Профиль", ПараметрыРасшифровки.СписокПолей["Профиль4"]);
			Если Не ЗначениеЗаполнено(Отбор.Профиль) Тогда
				Возврат;
			КонецЕсли;
		Иначе
			НачальнаяРоль = ЗначениеНачальногоОтбора(ФормаОтчета, "Роль");
			Если ЗначениеЗаполнено(НачальнаяРоль) Тогда
				Отбор.Вставить("Роль", НачальнаяРоль);
			Иначе
				УстановитьЗначениеПараметра(Отбор, "Роль", ФормаОтчета);
			КонецЕсли;
		КонецЕсли;
	Иначе
		Возврат;
	КонецЕсли;
	
	КлючНазначенияИспользования = КлючВарианта;
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "Роль");
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "Профиль");
	УточнитьКлючНазначенияИспользования(КлючНазначенияИспользования, Отбор, "ОбъектМетаданных");
	СократитьКлючНазначенияИспользования(КлючНазначенияИспользования);
	
	ФиксированныйОтбор = Новый Структура;
	Если Отбор.Свойство("ОбъектМетаданных")
	   И (    КлючВарианта = "ПодробныеПраваРолиНаОбъектМетаданных"
	      Или КлючВарианта = "ПраваРолейНаОбъектМетаданных") Тогда
		
		ФиксированныйОтбор.Вставить("ОбъектМетаданных", Отбор.ОбъектМетаданных);
		Отбор.Удалить("ОбъектМетаданных");
	КонецЕсли;
	ФиксированныйОтбор.Вставить("НачальныйОтбор", Отбор);
	
	ПараметрыОтчета.Вставить("Отбор", ФиксированныйОтбор);
	ПараметрыОтчета.Вставить("КлючВарианта", КлючВарианта);
	ПараметрыОтчета.Вставить("КлючНазначенияИспользования", КлючНазначенияИспользования);
	
	ОткрытьФорму(ФормаОтчета.НастройкиОтчета.ПолноеИмя + ".Форма", ПараметрыОтчета, ФормаОтчета);
	
КонецПроцедуры

// Для процедур ПриОбработкеРасшифровкиОтчетаАнализПравДоступа и
// ПриОбработкеРасшифровкиОтчетаПраваРолей.
//
Функция ЗначениеПараметра(КомпоновщикНастроек, ИмяПараметра, ИспользуетсяВсегда = Ложь)
	
	Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяПараметра);
	Настройка = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Параметр.ИдентификаторПользовательскойНастройки);
	
	Если Настройка <> Неопределено
	   И (ИспользуетсяВсегда Или Настройка.Использование) Тогда
		
		Возврат Настройка.Значение;
	КонецЕсли;
	
	Если Параметр <> Неопределено
	   И (ИспользуетсяВсегда Или Параметр.Использование) Тогда
		
		Возврат Параметр.Значение;
	КонецЕсли;
	
	Возврат Null;
	
КонецФункции

Функция ЗначениеНачальногоОтбора(ФормаОтчета, ИмяПараметра)
	
	Если ФормаОтчета.ФормаПараметры.Отбор.Свойство(ИмяПараметра) Тогда
		Отбор = ФормаОтчета.ФормаПараметры.Отбор;
		
	ИначеЕсли Не ФормаОтчета.ФормаПараметры.Отбор.Свойство("НачальныйОтбор") Тогда
		Возврат Неопределено;
	Иначе
		Отбор = ФормаОтчета.ФормаПараметры.Отбор.НачальныйОтбор;
		
		Если ТипЗнч(Отбор) <> Тип("Структура")
		 Или Не Отбор.Свойство(ИмяПараметра) Тогда
			Возврат Неопределено;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Отбор[ИмяПараметра];
	
КонецФункции

// Для процедур ПриОбработкеРасшифровкиОтчетаАнализПравДоступа и
// ПриОбработкеРасшифровкиОтчетаПраваРолей.
//
Процедура УточнитьКлючНазначенияИспользования(Ключ, Отбор, ИмяСвойства)
	
	Если Не Отбор.Свойство(ИмяСвойства) Тогда
		Возврат;
	КонецЕсли;
	
	Значение = Отбор[ИмяСвойства];
	Если Не ЗначениеЗаполнено(Значение) Тогда
		Возврат;
	КонецЕсли;
	
	ТипСсылки = Новый ОписаниеТипов(
		"СправочникСсылка.ИдентификаторыОбъектовМетаданных,
		|СправочникСсылка.ИдентификаторыОбъектовРасширений,
		|СправочникСсылка.Пользователи,
		|СправочникСсылка.ГруппыПользователей,
		|СправочникСсылка.ВнешниеПользователи,
		|СправочникСсылка.ГруппыВнешнихПользователей");
	
	Если ТипСсылки.СодержитТип(ТипЗнч(Значение)) Тогда
		Ключ = Ключ + "/" + Строка(Значение.УникальныйИдентификатор());
	ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
		Ключ = Ключ + "/" + Значение;
	КонецЕсли;
	
КонецПроцедуры

// Для процедур ПриОбработкеРасшифровкиОтчетаАнализПравДоступа и
// ПриОбработкеРасшифровкиОтчетаПраваРолей.
//
Процедура СократитьКлючНазначенияИспользования(КлючНазначенияИспользования)
	
	Если СтрДлина(КлючНазначенияИспользования) <= 128 Тогда
		Возврат;
	КонецЕсли;
	
	КлючНазначенияИспользования =
		УправлениеДоступомСлужебныйВызовСервера.СокращенныйКлючНазначенияИспользования(
			КлючНазначенияИспользования);
	
КонецПроцедуры

// Для процедуры ПриОбработкеРасшифровкиОтчетаАнализПравДоступа.
Функция ГруппировкаПоОтчетамВключена(КомпоновщикНастроек)
	
	Результат = Ложь;
	
	Элемент = НайтиЭлементГруппировкиПоИмени(КомпоновщикНастроек.Настройки.Структура, "ГруппировкаПоОтчетам");
	Если Элемент <> Неопределено Тогда
		Настройка = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(Элемент.ИдентификаторПользовательскойНастройки);
		Если Настройка <> Неопределено Тогда
			Результат = Настройка.Использование;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

// Для функции ГруппировкаПоОтчетамВключена
Функция НайтиЭлементГруппировкиПоИмени(КоллекцияЭлементов, Имя)
	
	Результат = Неопределено;
	
	Для Каждого Элемент Из КоллекцияЭлементов Цикл
		Если (ТипЗнч(Элемент) = Тип("ГруппировкаКомпоновкиДанных")
			Или ТипЗнч(Элемент) = Тип("ГруппировкаТаблицыКомпоновкиДанных"))
			И Элемент.Имя = Имя Тогда
			Результат = Элемент;
		ИначеЕсли ТипЗнч(Элемент) = Тип("ТаблицаКомпоновкиДанных") Тогда
			Результат = НайтиЭлементГруппировкиПоИмени(Элемент.Строки, Имя);
			Если Результат = Неопределено Тогда
				Результат = НайтиЭлементГруппировкиПоИмени(Элемент.Колонки, Имя);
			КонецЕсли;
		КонецЕсли;
		Если Результат <> Неопределено Тогда
			Возврат Результат;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Результат;
	
КонецФункции

// Для процедуры ПриОбработкеРасшифровкиОтчетаПраваРолей.
Процедура УстановитьЗначениеПараметра(Отбор, ИмяПараметра, ФормаОтчета, ИспользуетсяВсегда = Ложь)
	
	ЗначениеПараметра = ЗначениеПараметра(ФормаОтчета.Отчет.КомпоновщикНастроек, ИмяПараметра, ИспользуетсяВсегда);
	Если ЗначениеПараметра <> Null Тогда
		Отбор.Вставить(ИмяПараметра, ЗначениеПараметра);
	КонецЕсли;
	
КонецПроцедуры


// Для процедуры ПриНачалеВыбораЗначений
Процедура ПриНачалеВыбораЗначенийОтчетаАнализПравДоступа(ФормаОтчета, УсловияВыбора, ОповещениеОЗакрытии, СтандартнаяОбработка)
	
	Если УсловияВыбора.ИмяПоля <> "ОбъектМетаданных" Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	Коллекции = Новый СписокЗначений;
	Коллекции.Добавить("Справочники");
	Коллекции.Добавить("Документы");
	Коллекции.Добавить("ЖурналыДокументов");
	Коллекции.Добавить("ПланыВидовХарактеристик");
	Коллекции.Добавить("ПланыСчетов");
	Коллекции.Добавить("ПланыВидовРасчета");
	Коллекции.Добавить("РегистрыСведений");
	Коллекции.Добавить("РегистрыНакопления");
	Коллекции.Добавить("РегистрыБухгалтерии");
	Коллекции.Добавить("РегистрыРасчета");
	Коллекции.Добавить("БизнесПроцессы");
	Коллекции.Добавить("Задачи");
	
	Выбранные = ОбщегоНазначенияКлиент.СкопироватьРекурсивно(УсловияВыбора.Отмеченные);
	УдалитьОтключенныеЗначения(Выбранные);
	
	ПараметрыПодбора = Новый Структура;
	ПараметрыПодбора.Вставить("ВыбиратьСсылки", Истина);
	ПараметрыПодбора.Вставить("ВыбранныеОбъектыМетаданных", Выбранные);
	ПараметрыПодбора.Вставить("КоллекцииВыбираемыхОбъектовМетаданных", Коллекции);
	ПараметрыПодбора.Вставить("СпособГруппировкиОбъектов", "ПоРазделам,ПоВидам");
	ПараметрыПодбора.Вставить("Заголовок", НСтр("ru = 'Подбор таблиц'"));
	
	Контекст = Новый Структура;
	Контекст.Вставить("УсловияВыбора", УсловияВыбора);
	Контекст.Вставить("ОповещениеОЗакрытии", ОповещениеОЗакрытии);
	
	Обработчик = Новый ОписаниеОповещения("ПослеВыбораОбъектовМетаданных", ЭтотОбъект, Контекст);
	ОткрытьФорму("ОбщаяФорма.ВыборОбъектовМетаданных", ПараметрыПодбора,,,,, Обработчик);
	
КонецПроцедуры

// Для процедуры ПриНачалеВыбораЗначений
Процедура ПриНачалеВыбораЗначенийОтчетаПраваРолей(ФормаОтчета, УсловияВыбора, ОповещениеОЗакрытии, СтандартнаяОбработка)
	
	Если УсловияВыбора.ИмяПоля <> "Роль"
	   И УсловияВыбора.ИмяПоля <> "ОбъектМетаданных" Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	Выбранные = ОбщегоНазначенияКлиент.СкопироватьРекурсивно(УсловияВыбора.Отмеченные);
	УдалитьОтключенныеЗначения(Выбранные);
	Коллекции = Новый СписокЗначений;
	
	ПараметрыПодбора = Новый Структура;
	ПараметрыПодбора.Вставить("ВыбранныеОбъектыМетаданных", Выбранные);
	ПараметрыПодбора.Вставить("КоллекцииВыбираемыхОбъектовМетаданных", Коллекции);
	
	Если УсловияВыбора.ИмяПоля = "Роль" Тогда
		Для Каждого ЭлементСписка Из Выбранные Цикл
			ЭлементСписка.Значение = "Роль." + ЭлементСписка.Значение;
		КонецЦикла;
		ПараметрыПодбора.Вставить("СпособГруппировкиОбъектов", "ПоВидам");
		ПараметрыПодбора.Вставить("Заголовок", НСтр("ru = 'Подбор ролей'"));
		Коллекции.Добавить("Роли");
	Иначе
		ПараметрыПодбора.Вставить("СпособГруппировкиОбъектов", "ПоВидам,ПоРазделам");
		ПараметрыПодбора.Вставить("Заголовок", НСтр("ru = 'Подбор объектов метаданных'"));
		ПараметрыПодбора.Вставить("ВыбиратьКоллекцииКогдаВыбраныВсеОбъекты", Истина);
		ДобавитьКоллекцииОбъектовМетаданныхСПравами(Коллекции);
	КонецЕсли;
	
	Контекст = Новый Структура;
	Контекст.Вставить("УсловияВыбора", УсловияВыбора);
	Контекст.Вставить("ОповещениеОЗакрытии", ОповещениеОЗакрытии);
	
	Обработчик = Новый ОписаниеОповещения("ПослеВыбораОбъектовМетаданных", ЭтотОбъект, Контекст);
	ОткрытьФорму("ОбщаяФорма.ВыборОбъектовМетаданных", ПараметрыПодбора,,,,, Обработчик);
	
КонецПроцедуры

// Для процедуры ПриНачалеВыбораЗначений.
Процедура ПослеВыбораОбъектовМетаданных(ВыбранныеЗначения, Контекст) Экспорт
	
	Если Контекст.УсловияВыбора.ИмяПоля = "Роль"
	   И ЗначениеЗаполнено(ВыбранныеЗначения) Тогда
		
		Для Каждого ЭлементСписка Из ВыбранныеЗначения Цикл
			ЭлементСписка.Значение = СтрРазделить(ЭлементСписка.Значение, ".")[1];
		КонецЦикла;
	КонецЕсли;
	
	ВыполнитьОбработкуОповещения(Контекст.ОповещениеОЗакрытии, ВыбранныеЗначения);
	
КонецПроцедуры

// Для процедуры ПриНачалеВыбораЗначений.
Процедура УдалитьОтключенныеЗначения(ОтмеченныеЗначения)
	
	Индекс = ОтмеченныеЗначения.Количество() - 1;
	
	Пока Индекс >= 0 Цикл 
		Элемент = ОтмеченныеЗначения[Индекс];
		Индекс = Индекс - 1;
		
		Если Не ЗначениеЗаполнено(Элемент.Значение) Тогда 
			ОтмеченныеЗначения.Удалить(Элемент);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

// Для процедуры ПриНачалеВыбораЗначений.
Процедура ДобавитьКоллекцииОбъектовМетаданныхСПравами(Коллекции)
	
	Коллекции.Добавить("Подсистемы");
	Коллекции.Добавить("ПараметрыСеанса");
	Коллекции.Добавить("ОбщиеРеквизиты");
	Коллекции.Добавить("ПланыОбмена");
	Коллекции.Добавить("КритерииОтбора");
	Коллекции.Добавить("ОбщиеФормы");
	Коллекции.Добавить("ОбщиеКоманды");
	Коллекции.Добавить("WebСервисы");
	Коллекции.Добавить("HTTPСервисы");
	Коллекции.Добавить("Константы");
	Коллекции.Добавить("Справочники");
	Коллекции.Добавить("Документы");
	Коллекции.Добавить("ЖурналыДокументов");
	Коллекции.Добавить("Перечисления");
	Коллекции.Добавить("Отчеты");
	Коллекции.Добавить("Обработки");
	Коллекции.Добавить("ПланыВидовХарактеристик");
	Коллекции.Добавить("ПланыСчетов");
	Коллекции.Добавить("ПланыВидовРасчета");
	Коллекции.Добавить("РегистрыСведений");
	Коллекции.Добавить("РегистрыНакопления");
	Коллекции.Добавить("РегистрыБухгалтерии");
	Коллекции.Добавить("РегистрыРасчета");
	Коллекции.Добавить("БизнесПроцессы");
	Коллекции.Добавить("Задачи");
	Коллекции.Добавить("ВнешниеИсточникиДанных");
	
КонецПроцедуры

#КонецОбласти
